class ElementAbstract:
    def accept(self,visitor):
        pass

class ElementEngineer(ElementAbstract):
    def __init__(self,name,kpi) -> None:
        self.name = name
        self.kpi = kpi
    
    def accept(self, visitor):
        visitor.visit(self)
        
    def get_code_line_total(self):
        return self.kpi *10000
    
class ElementManager(ElementAbstract):
    def __init__(self,name,kpi) -> None:
        self.name = name
        self.kpi = kpi

    def accept(self, visitor):
        visitor.visit(self)
    
    def get_product_num(self):
        return self.kpi *2


class VisitorAbstract:
    def visit_engineer(self, engineer):
        pass
    
    def visit_manager(self, manager):
        pass

class VisitorCTO(VisitorAbstract):
    def visit(self, element):
        if isinstance(element, ElementEngineer):
            print(f'工程师：{element.name}今年代码量为: {element.get_code_line_total()}行')
        elif isinstance(element, ElementManager):
            print(f'管理：{element.name}今年参与的项目数： {element.get_product_num()}个')
        
    
class VisitorCEO(VisitorAbstract):
    def visit(self, element):
        if isinstance(element,ElementEngineer):
            print(f'工程师：{element.name}今年的KPI为{element.kpi}')
        elif isinstance(element,ElementManager):
            print(f'管理：{element.name}今年的KPI为{element.kpi}')
    
class Structure:
    def __init__(self) -> None:
        self.employees = []

    def add_employee(self, employee):
        self.employees.append(employee)
        
        return self

    def report(self, visitor):
        for employee in self.employees:
            employee.accept(visitor)
        

if __name__ == '__main__':
    # engineer = ElementEngineer('小张',7)
    # manager = ElementManager('程经理',8)
    # visitor_cto = VisitorCTO()
    #                             # 控制台输出内容：
    # visitor_cto.visit(engineer) # 工程师：小张今年代码量70000行
    # visitor_cto.visit(manager)  # 管理：程经理今年参与的项目数：16个

    # engineer = ElementEngineer('小张',7)
    # manager = ElementManager('程经理',8)
    # visitor_ceo = VisitorCEO()
    #                             # 控制台输出内容：
    # visitor_ceo.visit(engineer) # 工程师：小张今年的KPI为7
    # visitor_ceo.visit(manager)  # 管理：程经理今年的KPI为8
    engineer = ElementEngineer('小张',7)
    engineer_two = ElementEngineer('小李',8)
    manager = ElementManager('程经理',8)
    visitor_cto = VisitorCTO()
    struct = Structure()
    struct.add_employee(engineer).add_employee(engineer_two).add_employee(manager)
    struct.report(visitor_cto)